/**
 * 全局模块-牌型判断逻辑
 * @author none
 *
 */
class DZPKCardLogic extends CardLogic {
    public constructor() {
        super();
    }
    /** 花色掩码 **/
    public static MASK_COLOR: number = 0xF0;
    /** 数值掩码 **/
    public static MASK_VALUE: number = 0x0F;
    /** 获取数值 **/
    public static getCardValue(cardData: number): number {
        return (cardData & this.MASK_VALUE);
    }
    /** 获取花色 **/
    public static getCardColor(cardData: number): number {
        return (cardData & this.MASK_COLOR) / 16;
    }
    /** 根据值获取牌数据 **/
    public static getCardByValue(cardData: number[], cardValue: number): number {
        for (var i: number = 0; i < cardData.length; i++) {
            if (DZPKCardLogic.getCardValue(cardData[i]) == cardValue) {
                return cardData[i];
            }
        }
        return 0;
    }
    /** 组合自己的牌和公共牌 **/
    private static TogetherCardList(myCardList: number[], publicCardList: number[]): number[] {
        base.Utils.remove(myCardList, 0);
        base.Utils.remove(publicCardList, 0);
        return myCardList.concat(publicCardList);
    }
    /**
     * 获取牌型
     */
    public static getDZPKCardType(myCardList: number[], publicCardList: number[]): DZPKCardType {
        if (myCardList.length == 0) {
            return DZPKCardType.ERROR;
        }
        if (DZPKCardLogic.findBigStraightLine(myCardList, publicCardList).length > 0) {
            return DZPKCardType.BIGSTRAIGHTLINE;
        }
        if (DZPKCardLogic.findStraightLine(myCardList, publicCardList).length > 0) {
            return DZPKCardType.STRAIGHTLINE;
        }
        if (DZPKCardLogic.findFour(myCardList, publicCardList).length > 0) {
            return DZPKCardType.FOUR;
        }
        if (DZPKCardLogic.findFullHouse(myCardList, publicCardList).length > 0) {
            return DZPKCardType.FullHouse;
        }
        if (DZPKCardLogic.findStraight(myCardList, publicCardList).length > 0) {
            return DZPKCardType.STRAIGHT;
        }
        if (DZPKCardLogic.findLine(myCardList, publicCardList).length > 0) {
            return DZPKCardType.LINE;
        }
        if (DZPKCardLogic.findThree(myCardList, publicCardList).length > 0) {
            return DZPKCardType.THREE;
        }
        if (DZPKCardLogic.findTwo(myCardList, publicCardList).length > 1) {
            return DZPKCardType.TWODOUBLE;
        }
        if (DZPKCardLogic.findTwo(myCardList, publicCardList).length > 0) {
            return DZPKCardType.DOUBLE;
        }
        return DZPKCardType.SINGLE;
    }
    /**
    * 获取最大牌型的牌
    */
    public static getCardTypeCards(myCardList: number[], publicCardList: number[]): any {
        if (myCardList.length == 0) {
            return { cards: [], cardType: DZPKCardType.ERROR };
        }
        var cards: Array<number[]> = DZPKCardLogic.findBigStraightLine(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 皇家同花顺");
            return { cards: cards[0], cardType: DZPKCardType.BIGSTRAIGHTLINE };
        }
        cards = DZPKCardLogic.findStraightLine(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 同花顺");
            return { cards: cards[0], cardType: DZPKCardType.STRAIGHTLINE };
        }
        cards = DZPKCardLogic.findFour(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 四张");
            return { cards: cards[0], cardType: DZPKCardType.FOUR };
        }
        cards = DZPKCardLogic.findFullHouse(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 葫芦");
            return { cards: cards[0], myCardList, publicCardList, cardType: DZPKCardType.FullHouse };
        }
        cards = DZPKCardLogic.findStraight(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 同花");
            cards[0].length = 5;
            return { cards: cards[0], cardType: DZPKCardType.STRAIGHT };
        }
        cards = DZPKCardLogic.findLine(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 顺子");
            return { cards: cards[0], cardType: DZPKCardType.LINE };
        }
        cards = DZPKCardLogic.findThree(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 三张");
            return { cards: cards[0], cardType: DZPKCardType.THREE };
        }
        cards = DZPKCardLogic.findTwo(myCardList, publicCardList);
        if (cards.length > 1) {
            if (cards.length > 2) {
                cards = DZPKCardLogic.getMaxTwoPair(cards);
                //DZPKCardLogic.print(cards + " 两对");
                return { cards: cards[0].concat(cards[1]), cardType: DZPKCardType.TWODOUBLE };
            }
            //DZPKCardLogic.print(cards + " 两对");
            return { cards: cards[0].concat(cards[1]), cardType: DZPKCardType.TWODOUBLE };
        }
        cards = DZPKCardLogic.findTwo(myCardList, publicCardList);
        if (cards.length > 0) {
            //DZPKCardLogic.print(cards + " 一对");
            return { cards: cards[0], cardType: DZPKCardType.DOUBLE };
        }
        return { cards: [], cardType: DZPKCardType.SINGLE };
    }
    /** 查找顺子 **/
    private static findLine(myCardList: number[], publicCardList: number[], linelength: number = 5): Array<number[]> {
        var result: Array<number[]> = [];
        var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
        DZPKCardLogic.SortByCardData(cardData);
        var lineData: number[] = [];
        for (var i: number = 0; i < cardData.length; i++) {
            lineData.push(cardData[i]);
            for (var j: number = i + 1; j < cardData.length; j++) {
                if (((DZPKCardLogic.getCardValue(cardData[i]) == 1 ? 14 : DZPKCardLogic.getCardValue(cardData[i])) - DZPKCardLogic.getCardValue(cardData[j])) == lineData.length && //数字之间小于等于4
                    DZPKCardLogic.getCardValue(cardData[i]) != DZPKCardLogic.getCardValue(cardData[j])) {
                    lineData.push(cardData[j]);
                    if (lineData.length == linelength) {//5个已满
                        result.push(lineData);
                        break;
                    }
                } else {
                    continue;
                }
            }
            if (DZPKCardLogic.getCardValue(cardData[i]) == 1) {
                lineData = [];
                lineData.push(cardData[i]);
                for (var j: number = i + 1; j < cardData.length; j++) {
                    var isPush = false;
                    isPush = 1 - DZPKCardLogic.getCardValue(cardData[j]) == lineData.length - linelength && //数字之间小于等于-4
                        DZPKCardLogic.getCardValue(cardData[i]) != DZPKCardLogic.getCardValue(cardData[j]);
                    if (isPush) {
                        lineData.push(cardData[j]);
                        if (lineData.length == linelength) {//5个已满
                            result.push(lineData);
                            break;
                        }
                    }
                    else {
                        continue;
                    }
                }
            }
            lineData = [];
        }
        if (result.length > 1 && DZPKCardLogic.getCardValue(result[0][0]) == 1 && DZPKCardLogic.getCardValue(result[0][4]) == 2) {
            var temp = result[0];
            base.Utils.remove(result, result[0]);
            result.push(temp);
        }
        return result;
    }
    /**  查找同花顺**/
    private static findStraightLine(myCardList: number[], publicCardList: number[], linelength: number = 5): Array<number[]> {
        var straightList: Array<number[]> = DZPKCardLogic.findStraight(myCardList, publicCardList);//取出所有的同花
        var lineDataList: Array<number[]> = DZPKCardLogic.findLine(straightList.length > 0 ? straightList[0] : [], [], linelength);
        return lineDataList;
    }

    /**  查找皇家同花顺**/
    private static findBigStraightLine(myCardList: number[], publicCardList: number[], linelength: number = 5): Array<number[]> {
        var result: Array<number[]> = [];
        var lineDataList: Array<number[]> = DZPKCardLogic.findStraightLine(myCardList, publicCardList, linelength);//取出所有的同花
        for (var i: number = 0; i < lineDataList.length; i++) {
            //如果包含A和K
            if (DZPKCardLogic.getCardByValue(lineDataList[i], DZPKCardLogic.getCardValue(0x01)) != 0 && DZPKCardLogic.getCardByValue(lineDataList[i], DZPKCardLogic.getCardValue(0x0D)) != 0) {
                result.push(lineDataList[i]);
            }
        }
        return result;
    }
    /** 查找同花 **/
    private static findStraight(myCardList: number[], publicCardList: number[]): Array<number[]> {
        var result: Array<number[]> = [];
        var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
        DZPKCardLogic.SortByCardData(cardData);
        var objColor: Object = {};
        for (var i: number = 0; i < cardData.length; i++) {
            var color: number = DZPKCardLogic.getCardColor(cardData[i]);
            if (!objColor.hasOwnProperty(color.toString())) {
                objColor[color.toString()] = [];
            }
            objColor[color.toString()].push(cardData[i]);
        }

        var key: string;
        for (key in objColor) {
            if (objColor[key].length >= 5) {
                result.push(objColor[key]);
                break;
            }
        }

        return result;
    }
    /** 查找4张 **/
    private static findFour(myCardList: number[], publicCardList: number[]): Array<number[]> {
        var result: Array<number[]> = [];
        var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
        DZPKCardLogic.SortByCardData(cardData);
        for (var i: number = 0; i < cardData.length; i++) {
            if (i + 3 < cardData.length)//如果剩余有4张
            {
                if (DZPKCardLogic.getCardValue(cardData[i]) == DZPKCardLogic.getCardValue(cardData[i + 1])
                    && DZPKCardLogic.getCardValue(cardData[i + 1]) == DZPKCardLogic.getCardValue(cardData[i + 2])
                    && DZPKCardLogic.getCardValue(cardData[i + 2]) == DZPKCardLogic.getCardValue(cardData[i + 3]))//4张全部相等
                {
                    var fourData: number[] = [cardData[i], cardData[i + 1], cardData[i + 2], cardData[i + 3]];
                    result.push(fourData);
                }
            }
        }
        return result;
    }
    /** 查找3张 **/
    private static findThree(myCardList: number[], publicCardList: number[]): Array<number[]> {
        var result: Array<number[]> = [];
        var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
        DZPKCardLogic.SortByCardData(cardData);
        for (var i: number = 0; i < cardData.length; i++) {
            if (i + 2 < cardData.length)//如果剩余有4张
            {
                if (DZPKCardLogic.getCardValue(cardData[i]) == DZPKCardLogic.getCardValue(cardData[i + 1])
                    && DZPKCardLogic.getCardValue(cardData[i + 1]) == DZPKCardLogic.getCardValue(cardData[i + 2]))//3张全部相等
                {
                    var fourData: number[] = [cardData[i], cardData[i + 1], cardData[i + 2]];
                    result.push(fourData);
                }
            }
        }
        return result;
    }
    /** 查找2张 **/
    private static findTwo(myCardList: number[], publicCardList: number[]): Array<number[]> {
        var result: Array<number[]> = [];
        var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
        DZPKCardLogic.SortByCardData(cardData);
        for (var i: number = 0; i < cardData.length; i++) {
            if (i + 1 < cardData.length)//如果剩余有4张
            {
                if (DZPKCardLogic.getCardValue(cardData[i]) == DZPKCardLogic.getCardValue(cardData[i + 1]))//2张全部相等
                {
                    var fourData: number[] = [cardData[i], cardData[i + 1]];
                    result.push(fourData);
                }
            }
        }
        return result;
    }
    /** 查找葫芦 **/
    private static findFullHouse(myCardList: number[], publicCardList: number[]): Array<number[]> {
        var result: Array<number[]> = [];
        var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
        DZPKCardLogic.SortByCardData(cardData);
        var threeList: Array<number[]> = DZPKCardLogic.findThree(myCardList, publicCardList);//找出所有的三张
        if (threeList.length == 0) {
            return result;
        }
        for (var i: number = 0; i < threeList.length; i++) {
            var threeData: number[] = threeList[i];
            var newCardData: number[] = [];//踢除上面的三张
            for (var j: number = 0; j < cardData.length; j++) {
                if (threeData.indexOf(cardData[j]) == -1) {
                    newCardData.push(cardData[j]);
                }
            }
            var twoList: Array<number[]> = DZPKCardLogic.findTwo(newCardData, []);
            for (var a: number = 0; a < twoList.length; a++) {
                result.push(threeData.concat(twoList[a]));
            }
        }
        return result;
    }
    /** 根据牌值排序，从大到小，A最大 **/
    private static SortByCardData(cardData: number[]): void {
        // var self: DZPKCardLogic = DZPKCardLogic;
        cardData.sort((left, right) => {
            var leftVale: number = DZPKCardLogic.getCardValue(left);
            var rightVale: number = DZPKCardLogic.getCardValue(right);
            leftVale = leftVale == 1 ? 14 : leftVale;
            rightVale = rightVale == 1 ? 14 : rightVale;
            if (leftVale > rightVale) {
                return -1;
            }
            else if (leftVale < rightVale) {
                return 1;
            }
            else {
                return 0;
            }
        });
    }
    /*
     * 如果牌型中有三个对子，则拿出两个最大的对子
     * */
    private static getMaxTwoPair(cards: Array<number[]>): Array<number[]> {
        var cardValues = [];
        for (var i = 0; i < cards.length; i++) {
            if (DZPKCardLogic.getCardValue(cards[i][0]) == 1) {//判断是不是A
                cardValues.push(14);
            }
            else {
                cardValues.push(DZPKCardLogic.getCardValue(cards[i][0]));
            }
        }
        cards.splice(cardValues.indexOf(Math.min.apply(null, cardValues)), 1);//删除最小的对子
        return cards;
    }
    // /**
    //  * 获取最大牌型组合
    //  * 补齐五张最大牌型
    //  */
    // private getMaxCardGroup(typeCards:number[],myCardList: number[], publicCardList: number[]):number[]{
    //     var result: number[] = typeCards;
    //     if(typeCards.length==5){
    //         return typeCards;
    //     }
    //     var cardData: number[] = DZPKCardLogic.TogetherCardList(myCardList, publicCardList);
    //     DZPKCardLogic.SortByCardData(cardData);

    //     var newCardData: number[] = [];//踢除牌型中的牌
    //     for (var i: number = 0; i < cardData.length; i++) {
    //         if (typeCards.indexOf(cardData[i]) == -1) {
    //             newCardData.push(cardData[i]);
    //         }
    //     }
    //     for (var i: number = 0; i < newCardData.length; i++) {
    //         if (result.length>=5) {
    //             break;
    //         }
    //         else{
    //             result.push(newCardData[i]);
    //         }
    //     }
    //     return result;
    // }
}
